////////////////////////////////////////////////////////////////////////
// This file is part of the simpleSID framework
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
//
// Copyright (c)Richard White, 2009
// See License.txt for a disclaimer of all warranties
// and licensing information

#include "Voice.h"
#include "Filter.h"
#include <iostream>
#include <cmath>
using namespace std;

#pragma once
class RWSID
{
private:
	Voice	 m_Voice[3];
	Filter	 m_Filter;

	//static const int RBSIZE = 1 << 16;
	//static const int RBMASK = RBSIZE - 1;	
	//static const int RBBITs = 16; 
	
	//static const int FIRSIZE = 512;
	//static const int FIRMASK = FIRSIZE - 1;
	
	//static const float PI;

	float m_fSampleFreq;
	float m_fCyclesPerSample;
	float m_fSamplesPerCycle;
	//float m_fRingBuffer[RBSIZE];
	float m_fFracPos;
	int m_nReadPos;
	int m_nWritePos;

	//float m_fFIRTable[FIRSIZE + 1];
	
	//void MakeWindowedSinc();
	//float MakeSinc(float x);
	//float MakeHamming(float x);
	float Interpolate(float a, float b, float factor);
public:
	RWSID(float fSampleFreq);
	virtual ~RWSID();

	void InitSID();
	void ResetSID();
	
	//Just an enum for out tester functions 
	enum WaveType
	{
		kSaw,
		kPulse,
		kTri,
		kNoise
	};
	//This enum is for testing purposes
	enum FiltMode
	{
		kLP,
		kBP,
		kHP,
		k3Off
	};
	//Thses Are for writing directly for the sid registers
	unsigned char ReadSIDReg(unsigned char byOffset);
	void WriteSIDReg(unsigned char byOffset, unsigned char byValue);
	
	//Thse are testing functions
	void SetWaveForVoice(int nVoice, WaveType wt, bool bSet);
	void SetFreqForVoice(int nVoice, unsigned char Lo, unsigned char Hi);
	void SetPulseWidthForVoice(int nVoice, unsigned char Lo, unsigned char Hi);
	void SetTestForVoice(int nVoice, bool bTest);
	void SetSyncForVoice(int nVoice, bool bSync);
	void SetRingModForVoice(int nVoice, bool bRingMod);
	void SetAttackForVoice(int nVoice, unsigned char byAttack);
	void SetDecayForVoice(int nVoice, unsigned char byDecay);
	void SetSustainForVoice(int nVoice, unsigned char bySustain);
	void SetReleaseForVoice(int nVoice, unsigned char byRelease);
	void SetGateForVoice(int nVoice, bool bGate);
	void SetVol(unsigned char byVol);
	void SetMuteForVoice(int nVoice, bool bState);
	void SetFilterFreq(float fFreq);
	void SetFilterFCLo(unsigned char byFCLo);
	void SetFilterFCHi(unsigned char byFCHi);
	void SetFilterRes(unsigned char byRes);
	void SetFilterMode(FiltMode mode, bool bState);
	void SetFilterRouting(int nVoice, bool bState);
	void EnableFilter(bool bState);

	void ResetVoice(int nVoice);

	//These are for clocking for a few cycles
	void Process();
	void Process(int iCycles);

	float FloatOutput(); //This is just a scaled down output of everything
	
	int Render(float *fBuffer, unsigned long ulLen, int iCycles);
};